package org.mtmi.io.controls;

import java.io.IOException;

import net.n3.nanoxml.IXMLElement;

import org.mtmi.io.ReaderError;
import org.mtmi.io.SceneReader;
import org.mtmi.io.SceneWriter;
import org.mtmi.io.XMLReader;
import org.mtmi.io.XMLWriter;
import org.mtmi.ui.IAdaptable;
import org.mtmi.ui.controls.Control;
import org.mtmi.ui.controls.IValueGenerator;
import org.mtmi.ui.controls.midi.MidiController;

/**
 * In addition to {@link ControlIO}, save {@link MidiController} features:
 * <ul>
 * <li> back/foreground color.
 * <li> MIDI output
 * <li> MIDI channel
 * <li> MIDI control
 * <li> MIDI value
 * <li> control generating values, if any
 * </ul>
 */
public class MidiControllerIO extends ControlIO
{
	
	private static final String E_MC ="midiController"; //$NON-NLS-1$
	private static final String A_OUTPUT = "output"; //$NON-NLS-1$
	private static final String A_CHANNEL = "channel"; //$NON-NLS-1$
	private static final String A_CONTROL = "control"; //$NON-NLS-1$
	private static final String A_VALUE = "value"; //$NON-NLS-1$
	private static final String A_VALUE_CONTROLLER = "valueController"; //$NON-NLS-1$
	private static final String A_CID = "valueControllerCID"; //$NON-NLS-1$

	public MidiControllerIO() {
		setProcessFeature( F_BACKGROUND_COLOR, true );
		setProcessFeature( F_FOREGROUND_COLOR, true );
	}
	
	@Override
	public void writeControl( Control c, XMLWriter w, SceneWriter sw ) throws IOException 
	{
		super.writeControl( c, w, sw );
		
		//parameters
		MidiController mc = (MidiController)c;
		
		w.startElement( E_MC );
		boolean ai = w.setAttributeIndented( false );
		w.addAttr( A_OUTPUT, mc.getMidiOutput() );
		w.addAttr( A_CHANNEL, mc.getMidiChannel() );
		w.addAttr( A_CONTROL, mc.getMidiController() );
		w.addAttr( A_VALUE, mc.getMidiValue() );
		if( mc.getValueController()!=null ) {
			IValueGenerator vg = mc.getValueController();
			String cid = mc.getValueControllerConnectionId();
			if( vg instanceof IAdaptable ) {
				Control control = (Control)((IAdaptable)vg).getAdapter( Control.class, cid );
				if( control !=null ) {
					w.addAttr( A_VALUE_CONTROLLER, sw.getControlId( control ) );
					w.addAttr( A_CID, cid, (String)null );
				}
			}
		}
		w.endElement( E_MC );
		w.setAttributeIndented( ai );
	}
	
	@Override
	public void readControl( Control c, IXMLElement element, XMLReader r, SceneReader sr ) throws ReaderError 
	{
		super.readControl( c, element, r, sr );
		
		MidiController mc = (MidiController)c;
		
		//parameters:		
		IXMLElement e = r.getElement( element, E_MC, true );
		mc.setMidiOutput( r.getAttrInt( e, A_OUTPUT ) );
		mc.setMidiChannel( r.getAttrInt( e, A_CHANNEL) );
		mc.setMidiController( r.getAttrInt( e, A_CONTROL ) );
		mc.setMidiValue( r.getAttrInt( e, A_VALUE ) );
		
		int vc = r.getAttr( e, A_VALUE_CONTROLLER, 0 );
		if( vc > 0 ) {
			Control cvc = sr.getControl( vc );
			String cid  = r.getAttr( e, A_CID, (String)null );
			//if( cvc instanceof IAdaptable ) {
			IValueGenerator vg  = (IValueGenerator)((IAdaptable)cvc).getAdapter( IValueGenerator.class, cid );
			mc.setValueController( vg, cid );
			//}
		}
	}
}
